import { BaseProcessor } from './baseProcessor.js'
import mammoth from 'mammoth'
import logger from '../../services/logger.js'

export class DocxProcessor extends BaseProcessor {
  async process(filePath) {
    try {
      // 使用 mammoth 提取文本，保留样式信息
      const result = await mammoth.extractRawText({
        path: filePath,
        styleMap: [
          "p[style-name='TOC'] => remove",  // 移除 TOC 样式的段落
          "p[style-name='TOC1'] => remove", // 移除不同级别的 TOC
          "p[style-name='TOC2'] => remove",
          "p[style-name='TOC3'] => remove",
          "p[style-name='Contents'] => remove"
        ]
      })
      
      // 先进行基本的目录过滤
      let text = this.filterTableOfContents(result.value)
      
      // 增强的目录过滤
      text = this.enhancedTOCFilter(text)
      
      // 然后进行其他处理
      text = this.preprocessDocxText(text)
      
      return text
    } catch (error) {
      logger.error('DOCX 处理失败:', {
        filePath,
        error: error.message
      })
      throw new Error(`DOCX 处理失败: ${error.message}`)
    }
  }
  
  enhancedTOCFilter(text) {
    // 1. 移除常见的目录标记及其后续内容
    text = text.replace(/^(?:目\s*录|(?:Table\s+of\s+)?Contents)\s*(?:\n(?!第[一二三四五六七八九十]|Chapter|\d|Introduction|[一二三四五六七八九十]、).+)*\n*/im, '')
    
    // 2. 移除页码引用
    text = text.replace(/\.{2,}[\s\d]+(?:\n|$)/gm, '\n')
    
    // 3. 移除缩进式目录项
    text = text.replace(/(?:^\s+[\w\u4e00-\u9fa5].*?\.{2,}\s*\d+\s*$\n?)+/gm, '')
    
    // 4. 移除连续的短行（通常是目录项）
    text = text.replace(/(?:^.{1,50}(?:\.\s*\.+|\s{3,})\d+\s*$\n?){3,}/gm, '')
    
    // 5. 移除Word自动生成的图表目录
    text = text.replace(/^(?:图|表|Figure|Table)(?:\s+\d+)*\s*[:：].*?(?:\n|$)/gm, '')
    
    return text.trim()
  }
  
  preprocessDocxText(text) {
    return text
      // 移除连续的空行
      .replace(/\n{3,}/g, '\n\n')
      // 移除特殊字符
      .replace(/[\uFFFD\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, '')
      // 规范化空白字符
      .replace(/[ \t]+/g, ' ')
      // 处理分页符
      .replace(/\f/g, '\n\n')
      // 移除重复的空格
      .replace(/ {2,}/g, ' ')
      // 移除可能的页眉页脚
      .replace(/^.{1,50}(?:\n|$)/gm, (match) => {
        if (/^\s*(?:\d+|page|chapter|section|\u7b2c|\u9875|\u7ae0|\u8282)/i.test(match)) {
          return ''
        }
        return match
      })
      .trim()
  }
} 